package com.ellecity06.common.widgets.image

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Shader
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
import com.ellecity06.common.R
import com.ellecity06.common.ktx.colorResToColorId
import com.ellecity06.common.ktx.dimenResToInt

/**
 * @author zavier
 * @time 2024/10/28 10:33
 * @des 圆角图片
 */
class RoundImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {

    enum class RoundType {
        ROUND, CIRCLE
    }

    // 布局画笔
    private var roundImageViewPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG)

    // 背景画笔
    private var backgroundPaintPaint: Paint? = null

    // 边框画笔
    private var borderPaint: Paint? = null

    // 圆弧类型
    private var roundType = RoundType.ROUND.ordinal

    // 圆弧大小
    private var radius = R.dimen.dp_8.dimenResToInt()

    // 边框大小
    private var borderWidth = 0

    // 边框颜色
    private var borderColor = R.color.line_color.colorResToColorId()

    // 背景颜色
    private var roundImageViewBackgroundColor = Color.TRANSPARENT

    init {
        val typedArray =
            context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0)
        try {
            roundType = if (typedArray.hasValue(R.styleable.RoundImageView_riv_type)) {
                typedArray.getInt(R.styleable.RoundImageView_riv_type, RoundType.ROUND.ordinal)
            } else {
                RoundType.ROUND.ordinal
            }

            radius = if (typedArray.hasValue(R.styleable.RoundImageView_riv_radius)) {
                typedArray.getDimensionPixelSize(
                    R.styleable.RoundImageView_riv_radius,
                    R.dimen.dp_8.dimenResToInt()
                )
            } else {
                R.dimen.dp_8.dimenResToInt()
            }

            borderWidth = if (typedArray.hasValue(R.styleable.RoundImageView_riv_border_width)) {
                typedArray.getDimensionPixelSize(
                    R.styleable.RoundImageView_riv_border_width,
                    0
                )
            } else {
                0
            }

            borderColor = if (typedArray.hasValue(R.styleable.RoundImageView_riv_border_color)) {
                typedArray.getColor(
                    R.styleable.RoundImageView_riv_border_color,
                    R.color.line_color.colorResToColorId()
                )
            } else {
                R.color.line_color.colorResToColorId()
            }

            roundImageViewBackgroundColor =
                if (typedArray.hasValue(R.styleable.RoundImageView_riv_background_color)) {
                    typedArray.getColor(
                        R.styleable.RoundImageView_riv_background_color,
                        Color.TRANSPARENT
                    )
                } else {
                    Color.TRANSPARENT
                }
        } finally {
            typedArray.recycle()
        }

        // 初始化View
        initView()
    }

    /**
     * 初始化View
     */
    private fun initView() {
        if (roundImageViewBackgroundColor != Color.TRANSPARENT) {
            backgroundPaintPaint = Paint()
            backgroundPaintPaint?.style = Paint.Style.FILL
            backgroundPaintPaint?.isAntiAlias = true
            backgroundPaintPaint?.color = roundImageViewBackgroundColor
        }

        if (borderWidth != 0) {
            borderPaint = Paint()
            borderPaint?.style = Paint.Style.STROKE
            borderPaint?.isAntiAlias = true
            borderPaint?.color = borderColor
            borderPaint?.strokeWidth = borderWidth.toFloat()
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 当模式为圆形模式的时候，我们强制让宽高一致
        if (roundType == RoundType.CIRCLE.ordinal) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            val result = measuredHeight.coerceAtMost(measuredWidth)
            setMeasuredDimension(result, result)
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        }
    }

    /**
     * drawable转换成bitmap
     */
    private fun drawable2Bitmap(drawable: Drawable?): Bitmap? {
        if (drawable == null) {
            return null
        }

        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap) // 根据传递的scaleType获取matrix对象，bitmap
        val matrix = imageMatrix

        if (matrix != null) {
            canvas.concat(matrix)
        }

        drawable.draw(canvas)
        return bitmap
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        if (drawable == null) {
            return
        }

        if (drawable.intrinsicWidth == 0 || drawable.intrinsicHeight == 0) {
            return
        }

        if (imageMatrix == null && paddingTop == 0 && paddingLeft == 0) {
            drawable.draw(canvas)
        } else {
            val saveCount = canvas.saveCount
            canvas.save()
            if (cropToPadding) {
                val scrollX = scrollX
                val scrollY = scrollY
                canvas.clipRect(
                    scrollX + paddingLeft,
                    scrollY + paddingTop,
                    scrollX + right - left - paddingRight,
                    scrollY + bottom - top - paddingBottom
                )
            }
            canvas.translate(paddingLeft.toFloat(), paddingTop.toFloat())

            when (roundType) {
                // 圆角模式
                RoundType.ROUND.ordinal -> {
                    val bitmap = drawable2Bitmap(drawable)
                    roundImageViewPaint.shader = BitmapShader(
                        bitmap!!,
                        Shader.TileMode.CLAMP,
                        Shader.TileMode.CLAMP
                    )

                    // 是否有背景
                    if (backgroundPaintPaint != null) {
                        canvas.drawRoundRect(
                            RectF(
                                paddingLeft.toFloat(),
                                paddingTop.toFloat(),
                                (width - paddingRight).toFloat(),
                                (height - paddingBottom).toFloat()
                            ),
                            radius.toFloat(),
                            radius.toFloat(),
                            backgroundPaintPaint!!
                        )
                    }
                    // 开始画圆角矩形
                    val gap = borderWidth / 2
                    canvas.drawRoundRect(
                        RectF(
                            paddingLeft.toFloat() + gap,
                            paddingTop.toFloat() + gap,
                            (width - paddingRight - gap).toFloat(),
                            (height - paddingBottom - gap).toFloat()
                        ),
                        radius.toFloat(),
                        radius.toFloat(),
                        roundImageViewPaint
                    )
                    // 是否有边框线
                    if (borderPaint != null) {
                        canvas.drawRoundRect(
                            RectF(
                                paddingLeft.toFloat() + gap,
                                paddingTop.toFloat() + gap,
                                (width - paddingRight - gap).toFloat(),
                                (height - paddingBottom - gap).toFloat()
                            ),
                            radius.toFloat(),
                            radius.toFloat(),
                            borderPaint!!
                        )
                    }
                }

                // 圆形模式
                RoundType.CIRCLE.ordinal -> {
                    val bitmap = drawable2Bitmap(drawable)
                    roundImageViewPaint.shader = BitmapShader(
                        bitmap!!,
                        Shader.TileMode.CLAMP,
                        Shader.TileMode.CLAMP
                    )
                    // 是否有背景
                    if (backgroundPaintPaint != null) {
                        canvas.drawCircle(
                            (width / 2).toFloat(),
                            (height / 2).toFloat(),
                            (width / 2).toFloat(),
                            backgroundPaintPaint!!
                        )
                    }
                    // 开始画圆
                    canvas.drawCircle(
                        (width / 2).toFloat(),
                        (height / 2).toFloat(),
                        (width / 2).toFloat(),
                        roundImageViewPaint
                    )
                    // 是否有边框线
                    if (borderPaint != null) {
                        val gap = borderWidth / 2
                        canvas.drawCircle(
                            (width / 2).toFloat(),
                            (height / 2).toFloat(),
                            (width / 2).toFloat() - gap,
                            borderPaint!!
                        )
                    }
                }

                else -> {
                    if (imageMatrix != null) {
                        canvas.concat(imageMatrix)
                    }
                    drawable.draw(canvas)
                }
            }

            canvas.restoreToCount(saveCount)
        }
    }
}